package com.cskaoyan.javase.oop1._1basic;

/**
 * 对象的创建与使用
 * 案例: 创建学生对象,使用学生对象.
 *
 * 1.首先要想创建学生对象,需要先定义创建对象的模板——类
 * 创建学生类
 * 类的定义：
 * 定义类包括：
 *      a.定义类本身
 *      b.定义类中结构
 *
 * 定义类本身：
 * 语法:
 * [类修饰符列表] class 类名{
 *   // 类体
 * }
 * 解释:
 * 1.类修饰符列表,指的是能够用来修饰类的修饰组成的列表
 *      需要注意的是,Java中能够用来修饰类的修饰符非常少,我们一个也没学
 *      但是我们已经知道了:
 *      一个class要么是public class,要么是非public class
 *      一个Java文件下的所有class都是同包的关系,同包下不允许出现同名类
 *
 * 2.class是一个关键字,表示定义类.
 * 3.类名,大驼峰,见名知意,合法英文单词组成,类是创建对象的模板,是用来描述实体的
 *      所以类名往往是一个名词.
 *
 * 4.类体虽然也是大括号包裹,但它不是代码块,类体中定义的变量也不是局部变量
 *
 * 约定: 在实际的开发中,绝大多数情况下,一个java文件下就只有一个public class
 * 非常罕见定义非public class
 * 但是为了上课方便,查看代码,上课时,我们会经常定义非public class
 *
 * 注意事项(重要):
 * 很多同学经常测试,发现了class类的定义是可以嵌套的,这是一种特殊语法
 * 称之为"内部类"
 * 内部类是后面学习的一个难点,但是在今天,请大家不要定义内部类
 *
 * 定义类中的结构
 * 类是创建对象的模板,类抽取了同种类型对象,属性和行为的共性特征:
 *      1.我们抽象对象全体的共有"属性"，在类中用"成员变量"来描述对象共性的属性。
 *      2.我们抽象对象全体的共有"行为"，在类中用"成员方法"来描述对象共性的行为。
 *
 * 类中的成员变量
 * 什么是成员变量?
 * 与之相对应就是局部变量的概念
 * 局部变量: 定义在方法体,代码块等作用域内部的变量,是一个局部变量
 * 局部位置: 指的是方法体,代码块等作用域内部,定义在局部位置的变量就是一个局部变量.
 * 成员变量: 定义在成员位置的变量,就是一个成员变量
 * 成员位置: 在类体当中,局部位置之外的其他位置,都是成员位置
 * 成员变量定义的语法:
 *      [修饰符列表] 数据类型 变量名;
 * 解释:
 *      1.能够用来修饰成员变量的修饰很多,这里先略过,不加任何修饰,保持空着
 *      2.数据类型可以是基本数据类型,也可以是引用数据类型
 *      3.变量名见名知意,小驼峰,合法的英文单词组成...
 *
 * 类中的成员方法
 * 成员方法: 指的是定义在类中成员位置,且修饰符列表中没有static关键字的方法.
 * 语法:
 *      [访问权限修饰符] 返回值类型 方法名(形参列表){
 *          // 方法体
 *      }
 * 解释:
 *      1.访问权限修饰符还没有学习,这里就写public即可
 *      2.其它的返回值类型,形参,方法名等,定义和之前讲的方法没有区别.
 *
 *
 * 以上,定义完毕一个类,得到了一个学生类,得到了创建类的模板
 * 接下来,使用这个模板,创建学生对象.
 *
 * 创建学生对象,位置在哪里?
 *      一般来说,创建某个类的对象,都是在方法体当中
 *
 * 创建对象的语法(在方法体中创建):
 *      类名 对象名 = new 类名();
 * 解释:
 *      1.左右的类名一般是需要保持一致的
 *      2.以上语句可以类比于数组的初始化
 *          数据类型[] 数组名 = new 数据类型[长度];
 *      3.其中:
 *          类名 对象名 是创建对象的声明部分
 *          声明了这个对象的数据类型,以及它的对象名
 *          它是一个引用,是一个局部变量,存储在方法的栈帧中
 *
 *          右边 new 类名();
 *          new关键字表示在堆上开辟空间,创建对象
 *
 *          以上,创建对象的语法和创建数组对象的语法,其实是一样的.
 *
 * 对象创建完毕后,如何使用对象?
 * 包含:
 *      1.访问对象的属性
 *      2.调用对象的行为
 * 在目前这个阶段,以上都是使用"对象名."去访问/调用
 *
 * 成员变量和数组对象中的元素一样,它具有默认初始化,具有默认值,它的默认值和数组元素是一样的
 *
 * 以上总结思考:
 * 1.类中定义的成员变量以及成员方法,它们应该如何使用呢?
 * 必须创建对象/必须要有一个对象,然后用"对象名点"访问,没有对象是不可能访问成员变量/方法的
 * 所以我们也经常说:
 * 成员变量/方法,它们是属于对象的
 *
 * 2.输出对象名和输出数组名类似,默认情况下,会打印类的全限定类名以及十六进制地址值(这个字符串是可以修改的)
 *
 * 3.局部变量的作用域仅限于大括号内部
 * 但是成员变量,它的作用域是整个类中都可以访问
 * 尤其是类中的成员方法中,可以无条件直接访问
 *
 *
 * @since 15:10
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    // 成员位置

    public static void main(String[] args) {
        // 创建Student类的对象
        /*Student s;
        System.out.println(s);*/
        Student s = new Student();
        System.out.println(s.name);
        System.out.println(s.age);
        System.out.println(s.score);

        s.study();
        s.sleep();

        /*
            com.cskaoyan.javase.oop1._1basic.Student@1540e19d
            全限定类名 + 十六进制地址值
         */
        System.out.println(s);

        Student s2 = new Student();
        System.out.println(s == s2);

        s2.name = "张三";
        s2.study();
    }

    // 成员位置
    /*// 内部类
    class A{}
    class Student{}*/
}

// 学生类
class Student {
    /*
        类中抽取了全体对象,在属性上的共性
        得到了成员变量
     */
    String name;
    int age;
    int id;
    double score;

    /*
        类中抽取了全体对象,在行为上的共性
        得到了成员方法
     */
    public void study() {
        System.out.println(name + "好好学习,天天向上!");
    }

    public void sleep() {
        System.out.println("你这个年龄段,你怎么睡得着的?");
    }
}